#include "raylib.h"
#include <vector>
#include <string>
#include <algorithm> // For std::max and std::min
#include <cmath>     // For fmax, fabs

// --- Configuration ---
// int initial_inputA = 98; // 第一个数字 (可以修改)
// int initial_inputB = 56; // 第二个数字 (可以修改)

int initial_inputA = 107; // 第一个数字 (互质的情况)
int initial_inputB = 56; // 第二个数字 (互质的情况)

const int SCREEN_WIDTH = 1000;
const int SCREEN_HEIGHT = 700;
// const int RECT_HEIGHT = 60;      // 不再固定矩形高度
const int UI_AREA_HEIGHT = 150;  // 底部UI区域高度
const int VISUAL_AREA_START_X = 50;
const int VISUAL_AREA_START_Y = 60;
const int VISUAL_AREA_MAX_WIDTH = SCREEN_WIDTH - 2 * VISUAL_AREA_START_X;
const int VISUAL_AREA_MAX_HEIGHT = SCREEN_HEIGHT - UI_AREA_HEIGHT - VISUAL_AREA_START_Y - 20;


// --- Colors ---
Color COLOR_BACKGROUND_RECT = { 230, 230, 230, 255 }; // Light gray for the main area
Color COLOR_DIVIDEND_BORDER = ORANGE; // Border for the rect being divided
Color COLOR_SQUARE_FILL = {0, 228, 48, 200};  // Green (semi-transparent)
Color COLOR_SQUARE_BORDER = DARKGREEN;
Color COLOR_REMAINDER_FILL = {255, 0, 0, 200};   // Red (semi-transparent)
Color COLOR_REMAINDER_BORDER = MAROON;
Color COLOR_GCD_HIGHLIGHT_FILL = {255, 215, 0, 220}; // Gold
Color COLOR_GCD_HIGHLIGHT_BORDER = DARKBROWN;
Color COLOR_TEXT = DARKGRAY;
Color COLOR_BUTTON = LIGHTGRAY;
Color COLOR_BUTTON_TEXT = BLACK;

// --- Data Structures ---
struct VisualStep {
    int step_num;
    int dividend_val;    // 数值上的被除数 (总是较大的那个)
    int divisor_val;     // 数值上的除数 (总是较小的那个)
    int quotient_val;
    int remainder_val;

    Rectangle rect_to_be_tiled_pixel; // 当前步骤中被分割的矩形的像素坐标和尺寸
    bool is_tiling_vertical;          // true: dividend_val 对应高度, divisor_val 对应宽度 (高瘦型矩形)
                                      // false: dividend_val 对应宽度, divisor_val 对应高度 (矮胖型矩形)
    bool is_initial_display;          // 特殊标记，用于显示初始矩形
    bool is_final_step;
    int gcd_val;
    std::string description_text;
};

std::vector<VisualStep> steps_log;
int current_display_step_index = -1; // 从-1开始，这样第一个有效步骤是0

// 用于计算过程的变量
int current_math_A; // 当前用于计算的较大数
int current_math_B; // 当前用于计算的较小数

// 下一步将被分割的矩形的像素信息
Rectangle next_rect_to_tile_pixels;
bool next_rect_tiling_is_vertical; // 这个矩形在屏幕上是高是矮

bool algorithm_is_finished = false;
float master_unit_scale = 1.0f; // 全局统一的缩放比例

// --- Function Declarations ---
void ResetAlgorithmState(int inputA, int inputB);
void ProcessNextStep();
void DrawVisualization(); // 改名以反映其绘制所有步骤的性质
void DrawUIControls();    // 分离UI绘制

// --- Main Function ---
int main(void) {
    InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Raylib GCD Visualizer - Geometric Euclidean Algorithm");
    SetTargetFPS(60);

    ResetAlgorithmState(initial_inputA, initial_inputB);

    Rectangle next_button_rect = { (float)SCREEN_WIDTH / 2 - 120, (float)SCREEN_HEIGHT - UI_AREA_HEIGHT + 30, 100, 40 };
    Rectangle reset_button_rect = { (float)SCREEN_WIDTH / 2 + 20, (float)SCREEN_HEIGHT - UI_AREA_HEIGHT + 30, 100, 40 };

    while (!WindowShouldClose()) {
        // --- Update ---
        if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
            Vector2 mouse_pos = GetMousePosition();
            if (CheckCollisionPointRec(mouse_pos, next_button_rect)) {
                ProcessNextStep();
            }
            if (CheckCollisionPointRec(mouse_pos, reset_button_rect)) {
                ResetAlgorithmState(initial_inputA, initial_inputB);
            }
        }
         if (IsKeyPressed(KEY_RIGHT)) ProcessNextStep();
         if (IsKeyPressed(KEY_R)) ResetAlgorithmState(initial_inputA, initial_inputB);


        // --- Draw ---
        BeginDrawing();
        ClearBackground(RAYWHITE);

        DrawVisualization();
        DrawUIControls(); // 绘制按钮和状态文本

        // Draw Buttons (UI部分已移至DrawUIControls，这里保留按钮绘制逻辑，或将其也移入)
        DrawRectangleRec(next_button_rect, COLOR_BUTTON);
        DrawText("Next (->)", next_button_rect.x + 10, next_button_rect.y + 10, 20, COLOR_BUTTON_TEXT);
        DrawRectangleRec(reset_button_rect, COLOR_BUTTON);
        DrawText("Reset (R)", reset_button_rect.x + 10, reset_button_rect.y + 10, 20, COLOR_BUTTON_TEXT);

        DrawText("Geometric Euclidean Algorithm GCD Visualization", 20, 20, 20, DARKBLUE);
        DrawLine(0, SCREEN_HEIGHT - UI_AREA_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - UI_AREA_HEIGHT, LIGHTGRAY);

        EndDrawing();
    }

    CloseWindow();
    return 0;
}

void ResetAlgorithmState(int inputA, int inputB) {
    steps_log.clear();
    current_display_step_index = -1; // 重置显示步骤
    algorithm_is_finished = false;

    int absA = abs(inputA);
    int absB = abs(inputB);

    current_math_A = std::max(absA, absB);
    current_math_B = std::min(absA, absB);

    if (current_math_A == 0 && current_math_B == 0) { // 特殊情况 GCD(0,0)
        master_unit_scale = 10.0f; // 任意值
        next_rect_to_tile_pixels = { (float)VISUAL_AREA_START_X, (float)VISUAL_AREA_START_Y, 0, 0 };
        algorithm_is_finished = true; // 立即结束
         VisualStep initial_step;
        initial_step.step_num = 0;
        initial_step.dividend_val = 0;
        initial_step.divisor_val = 0;
        initial_step.quotient_val = 0;
        initial_step.remainder_val = 0;
        initial_step.rect_to_be_tiled_pixel = next_rect_to_tile_pixels;
        initial_step.is_tiling_vertical = false;
        initial_step.is_initial_display = true;
        initial_step.is_final_step = true;
        initial_step.gcd_val = 0; // GCD(0,0) 通常定义为0或未定义
        initial_step.description_text = "GCD(0, 0) = 0";
        steps_log.push_back(initial_step);
        current_display_step_index = 0;
        return;
    }
     if (current_math_B == 0) { // 如果初始较小数为0, GCD是较大数
        master_unit_scale = VISUAL_AREA_MAX_WIDTH / (float)fmax(1.0f, current_math_A);
        master_unit_scale = fmin(master_unit_scale, VISUAL_AREA_MAX_HEIGHT / (float)fmax(1.0f, 10.0f)); // 给一个最小高度
        next_rect_to_tile_pixels = {
            (float)VISUAL_AREA_START_X,
            (float)VISUAL_AREA_START_Y,
            current_math_A * master_unit_scale,
            10.0f * master_unit_scale // 显示一个细条
        };
        algorithm_is_finished = true;
        VisualStep initial_step;
        initial_step.step_num = 0;
        initial_step.dividend_val = current_math_A;
        initial_step.divisor_val = 0;
        initial_step.quotient_val = 0;
        initial_step.remainder_val = 0;
        initial_step.rect_to_be_tiled_pixel = next_rect_to_tile_pixels;
        initial_step.is_tiling_vertical = false;
        initial_step.is_initial_display = true;
        initial_step.is_final_step = true;
        initial_step.gcd_val = current_math_A;
        initial_step.description_text = TextFormat("Initial: %d, %d. GCD = %d", current_math_A, 0, current_math_A);
        steps_log.push_back(initial_step);
        current_display_step_index = 0;
        return;
    }


    // 计算 master_unit_scale 以适应初始矩形
    float scale_w = VISUAL_AREA_MAX_WIDTH / (float)current_math_A;
    float scale_h = VISUAL_AREA_MAX_HEIGHT / (float)current_math_B;
    master_unit_scale = fmin(scale_w, scale_h);
    master_unit_scale = fmax(1.0f, master_unit_scale); // 确保最小为1像素/单位

    next_rect_to_tile_pixels.x = VISUAL_AREA_START_X;
    next_rect_to_tile_pixels.y = VISUAL_AREA_START_Y;
    next_rect_to_tile_pixels.width = current_math_A * master_unit_scale;
    next_rect_to_tile_pixels.height = current_math_B * master_unit_scale;

    // 初始矩形，我们总是让 dividend_val (current_math_A) 对应宽度，divisor_val (current_math_B) 对应高度
    next_rect_tiling_is_vertical = false; // 因为 current_math_A 是宽度 (长边)

    // 添加一个代表初始状态的步骤
    VisualStep initial_step;
    initial_step.step_num = 0;
    initial_step.dividend_val = current_math_A; // 初始矩形的长边
    initial_step.divisor_val = current_math_B;  // 初始矩形的短边
    initial_step.quotient_val = 0; // 无计算
    initial_step.remainder_val = 0; // 无计算
    initial_step.rect_to_be_tiled_pixel = next_rect_to_tile_pixels;
    initial_step.is_tiling_vertical = next_rect_tiling_is_vertical; // 初始矩形的绘制方向
    initial_step.is_initial_display = true;
    initial_step.is_final_step = false;
    initial_step.gcd_val = 0;
    initial_step.description_text = TextFormat("Initial Rectangle: %d x %d", current_math_A, current_math_B);
    steps_log.push_back(initial_step);
    current_display_step_index = 0; // 显示初始状态
}

void ProcessNextStep() {
    if (algorithm_is_finished) {
        // 如果已经完成，但用户可能在查看中间步骤，允许他们前进到最后一步
        if (current_display_step_index < (int)steps_log.size() - 1) {
            current_display_step_index++;
        }
        return;
    }
    // 如果当前显示不是最新的已计算步骤，则仅推进显示
    if (current_display_step_index < (int)steps_log.size() - 1) {
         current_display_step_index++;
         // 检查新显示的步骤是否是最后一步
         if (!steps_log.empty() && steps_log[current_display_step_index].is_final_step) {
            algorithm_is_finished = true;
         }
        return;
    }


    if (current_math_B == 0) { // 算法已在上一步的准备阶段判定结束
        algorithm_is_finished = true;
        if (!steps_log.empty() && !steps_log.back().is_final_step) { // 确保最后一步被标记
            steps_log.back().is_final_step = true;
            steps_log.back().gcd_val = steps_log.back().dividend_val; // 此时dividend是GCD
            steps_log.back().description_text += TextFormat(" -> Divisor is 0. GCD = %d", steps_log.back().gcd_val);
        }
        return;
    }

    VisualStep new_step;
    new_step.step_num = steps_log.size(); // 基于0的索引，所以size是下一个编号
    new_step.dividend_val = current_math_A;
    new_step.divisor_val = current_math_B;
    new_step.quotient_val = current_math_A / current_math_B;
    new_step.remainder_val = current_math_A % current_math_B;
    new_step.rect_to_be_tiled_pixel = next_rect_to_tile_pixels; // 这个矩形是当前步骤要分割的
    new_step.is_tiling_vertical = next_rect_tiling_is_vertical; // 这个矩形的绘制方向
    new_step.is_initial_display = false; // 不是初始显示了
    new_step.description_text = TextFormat("Step %d: Divide %d by %d. %d = %d * %d + %d",
                                           new_step.step_num,
                                           new_step.dividend_val, new_step.divisor_val,
                                           new_step.dividend_val, new_step.divisor_val, new_step.quotient_val, new_step.remainder_val);

    // 为下一个迭代准备数学上的 A 和 B
    int prev_math_A = current_math_A; // 保存一下，用于计算下一个矩形
    int prev_math_B = current_math_B;

    current_math_A = prev_math_B; // 旧的除数成为新的被除数
    current_math_B = new_step.remainder_val; // 余数成为新的除数

    // 计算下一个要平铺的矩形的像素信息 (这个矩形是根据上一步的余数来的)
    if (new_step.remainder_val > 0) {
        if (new_step.is_tiling_vertical) { // 当前是高瘦型，余数在底部，形成矮胖型
            next_rect_to_tile_pixels.x = new_step.rect_to_be_tiled_pixel.x;
            next_rect_to_tile_pixels.y = new_step.rect_to_be_tiled_pixel.y + new_step.quotient_val * prev_math_B * master_unit_scale;
            next_rect_to_tile_pixels.width = prev_math_B * master_unit_scale; // 新矩形的宽度是旧的除数（短边）
            next_rect_to_tile_pixels.height = new_step.remainder_val * master_unit_scale; // 新矩形的高度是余数
            next_rect_tiling_is_vertical = false; // 下一个矩形是矮胖型 (宽度 > 高度，因为 prev_math_B > new_step.remainder_val)
        } else { // 当前是矮胖型，余数在右边，形成高瘦型
            next_rect_to_tile_pixels.x = new_step.rect_to_be_tiled_pixel.x + new_step.quotient_val * prev_math_B * master_unit_scale;
            next_rect_to_tile_pixels.y = new_step.rect_to_be_tiled_pixel.y;
            next_rect_to_tile_pixels.width = new_step.remainder_val * master_unit_scale; // 新矩形的宽度是余数
            next_rect_to_tile_pixels.height = prev_math_B * master_unit_scale; // 新矩形的高度是旧的除数（短边）
            next_rect_tiling_is_vertical = true; // 下一个矩形是高瘦型 (高度 > 宽度)
        }
    } else { // 余数为0，算法结束
        algorithm_is_finished = true;
        new_step.is_final_step = true;
        new_step.gcd_val = prev_math_B; // 当余数为0时，GCD是上一步的除数
        new_step.description_text += TextFormat(" -> Remainder is 0. GCD = %d", new_step.gcd_val);
        // next_rect_to_tile_pixels 不需要更新，因为没有下一个要平铺的了
        // 但是，我们需要确定哪个是GCD方块
        // GCD方块是上一步的除数形成的方块，它的大小是 gcd_val x gcd_val
        // 它的位置是 new_step.rect_to_be_tiled_pixel 中最后一个 prev_math_B 的方块
    }

    steps_log.push_back(new_step);
    current_display_step_index++; // 移动显示到这个新步骤
}


void DrawVisualization() {
    if (current_display_step_index < 0 || steps_log.empty()) return;

    // 只绘制当前步骤的细节，但背景可以是之前步骤的累积效果（如果需要）
    // 为了简化，我们每次都重绘所有相关矩形，但只高亮当前步骤的活动区域

    const VisualStep& step_to_draw = steps_log[current_display_step_index];

    // 绘制所有步骤的矩形，但只有当前步骤的矩形是活动的
    for (int i = 0; i <= current_display_step_index; ++i) {
        const VisualStep& s = steps_log[i];

        if (s.is_initial_display) {
            DrawRectangleRec(s.rect_to_be_tiled_pixel, COLOR_BACKGROUND_RECT);
            DrawRectangleLinesEx(s.rect_to_be_tiled_pixel, 2, COLOR_DIVIDEND_BORDER);
            DrawText(TextFormat("%d", s.dividend_val), s.rect_to_be_tiled_pixel.x + s.rect_to_be_tiled_pixel.width/2 -10, s.rect_to_be_tiled_pixel.y - 20, 20, COLOR_TEXT);
            DrawText(TextFormat("%d", s.divisor_val), s.rect_to_be_tiled_pixel.x - 25, s.rect_to_be_tiled_pixel.y + s.rect_to_be_tiled_pixel.height/2 -10, 20, COLOR_TEXT);
            continue;
        }

        // 绘制当前步骤正在被分割的矩形背景
        DrawRectangleRec(s.rect_to_be_tiled_pixel, Fade(COLOR_BACKGROUND_RECT, 0.5f));
        if (i == current_display_step_index) { // 高亮当前活动分割的矩形边框
             DrawRectangleLinesEx(s.rect_to_be_tiled_pixel, 3, RED);
        } else {
             DrawRectangleLinesEx(s.rect_to_be_tiled_pixel, 1, LIGHTGRAY);
        }


        float square_side_pixels = s.divisor_val * master_unit_scale;
        float current_x = s.rect_to_be_tiled_pixel.x;
        float current_y = s.rect_to_be_tiled_pixel.y;

        // 绘制商所代表的正方形
        for (int k = 0; k < s.quotient_val; ++k) {
            Rectangle square_rec;
            if (s.is_tiling_vertical) { // 高瘦型，竖着切方块
                square_rec = {current_x, current_y, square_side_pixels, square_side_pixels};
                current_y += square_side_pixels;
            } else { // 矮胖型，横着切方块
                square_rec = {current_x, current_y, square_side_pixels, square_side_pixels};
                current_x += square_side_pixels;
            }
            DrawRectangleRec(square_rec, COLOR_SQUARE_FILL);
            DrawRectangleLinesEx(square_rec, 1, COLOR_SQUARE_BORDER);
            DrawText(TextFormat("%d", s.divisor_val), square_rec.x + 5, square_rec.y + 5, 15, WHITE);
        }

        // 绘制余数矩形
        if (s.remainder_val > 0) {
            Rectangle remainder_rec;
            if (s.is_tiling_vertical) {
                remainder_rec = {s.rect_to_be_tiled_pixel.x, current_y,
                                 s.divisor_val * master_unit_scale, s.remainder_val * master_unit_scale};
            } else {
                remainder_rec = {current_x, s.rect_to_be_tiled_pixel.y,
                                 s.remainder_val * master_unit_scale, s.divisor_val * master_unit_scale};
            }
            DrawRectangleRec(remainder_rec, COLOR_REMAINDER_FILL);
            DrawRectangleLinesEx(remainder_rec, 1, COLOR_REMAINDER_BORDER);
            DrawText(TextFormat("%d", s.remainder_val), remainder_rec.x + 5, remainder_rec.y + 5, 15, WHITE);
        }

        // 如果是最后一步，高亮GCD方块
        if (s.is_final_step && s.gcd_val > 0) {
            // GCD方块是上一个除数形成的方块，它的大小是 gcd_val x gcd_val
            // 它位于被分割矩形的最后一个 "商" 方块的位置
            Rectangle gcd_square_rec;
            float gcd_side_pixels = s.gcd_val * master_unit_scale;

            // 定位最后一个除数方块（即GCD方块）
            // 这个逻辑需要基于 s.rect_to_be_tiled_pixel 和 s.quotient_val 来确定
            // 如果 s.quotient_val > 0, 最后一个方块是第 s.quotient_val - 1 个
            // 如果 s.quotient_val == 0 (例如 GCD(7,7) -> 7 = 7*1 + 0, 下一步是 GCD(7,0) )
            // 那么 GCD 是 dividend_val 本身，此时的 rect_to_be_tiled_pixel 就是 GCD 矩形
            // 但我们的逻辑是当 r=0 时，gcd_val 是上一步的 divisor_val.

            // 找到构成GCD的那个正方形。这个正方形是上一步的除数，也就是当前步骤的被除数（如果余数为0）
            // 或者，如果余数不为0，它就是当前步骤的除数。
            // 当 is_final_step 为 true 时，s.gcd_val 就是那个边长。
            // 我们需要找到这个 s.gcd_val x s.gcd_val 的方块。
            // 这个方块是 s.rect_to_be_tiled_pixel 内部的第一个（也是唯一一个，因为商是1）方块。

            // 实际上，当 is_final_step 为 true 时，s.remainder_val 必须为 0。
            // 此时，s.dividend_val = s.gcd_val * s.quotient_val (因为 s.divisor_val == s.gcd_val)
            // 我们要高亮的是 s.divisor_val (即 s.gcd_val) 构成的方块。
            // 这些方块就是上面循环中绘制的 COLOR_SQUARE_FILL 方块。
            // 我们需要高亮所有这些方块。

            float highlight_x = s.rect_to_be_tiled_pixel.x;
            float highlight_y = s.rect_to_be_tiled_pixel.y;
            for (int k = 0; k < s.quotient_val; ++k) {
                 Rectangle highlight_rec;
                 if (s.is_tiling_vertical) {
                    highlight_rec = {highlight_x, highlight_y + k * gcd_side_pixels, gcd_side_pixels, gcd_side_pixels};
                 } else {
                    highlight_rec = {highlight_x + k * gcd_side_pixels, highlight_y, gcd_side_pixels, gcd_side_pixels};
                 }
                 DrawRectangleRec(highlight_rec, COLOR_GCD_HIGHLIGHT_FILL);
                 DrawRectangleLinesEx(highlight_rec, 2, COLOR_GCD_HIGHLIGHT_BORDER);
                 DrawText(TextFormat("%d", s.gcd_val), highlight_rec.x + 5, highlight_rec.y + 5, 15, BLACK);
            }
             DrawText(TextFormat("GCD = %d", s.gcd_val), s.rect_to_be_tiled_pixel.x, s.rect_to_be_tiled_pixel.y + s.rect_to_be_tiled_pixel.height + 10, 25, DARKGREEN);
        }
    }
     // 在所有绘制的顶部显示当前步骤的描述文本
    if (current_display_step_index >= 0 && current_display_step_index < steps_log.size()) {
        DrawText(steps_log[current_display_step_index].description_text.c_str(), VISUAL_AREA_START_X, VISUAL_AREA_START_Y - 25, 20, DARKBLUE);
    }
}


void DrawUIControls() {
    std::string status_text;
    if (current_display_step_index < 0 || steps_log.empty()) {
        status_text = "Status: Initializing. Press Next or R.";
    } else {
        const VisualStep& current_step_info = steps_log[current_display_step_index];
        if (current_step_info.is_initial_display && !algorithm_is_finished) {
             status_text = "Status: Showing initial rectangle. Press Next.";
        } else {
            status_text = TextFormat("Displaying Step: %d / %lu", current_step_info.step_num, steps_log.size() -1);
            if (algorithm_is_finished && current_display_step_index == (int)steps_log.size() -1) {
                 status_text += TextFormat(" (Finished! GCD = %d)", current_step_info.gcd_val);
            } else if (algorithm_is_finished) {
                status_text += " (Algorithm Finished. Viewing intermediate step.)";
            }
        }
    }
    DrawText(status_text.c_str(), 20, SCREEN_HEIGHT - UI_AREA_HEIGHT + 90, 20, COLOR_TEXT);

    // 当前计算的数学值 (用于下一个ProcessNextStep)
    if (!algorithm_is_finished) {
         DrawText(TextFormat("Next to process: A=%d, B=%d", current_math_A, current_math_B), 20, SCREEN_HEIGHT - UI_AREA_HEIGHT + 60, 20, DARKPURPLE);
    }
}